package com.example.demotype;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author: 迟家鑫
 * @date: 2021/1/16 17:23
 * @description:
 */
public class ParameterizedTypeTest<T> {

    private List<T> list = null;
    private Set<T> set = null;
    private List<String> stringList = null;
    private Map<String, Integer> map = null;
    private Map.Entry<String, Integer> mapEntry = null;

    public static void main(String[] args) throws Exception {
        // 1.ParameterizedType表示参数化类型，也就是泛型，例如List<T>, Set<T>等；
        Field field = ParameterizedTypeTest.class.getDeclaredField("list");
        Type genericType = field.getGenericType();
        String name = genericType.getClass().getName();
        // System.out.println("Class Name: "+name);
        // System.out.println("Type Name: "+genericType);

        String fieldName = "map";
        // testParameterizedType(fieldName);

        // System.out.println("--------------------");

        fieldName = "mapEntry";
        // testParameterizedType(fieldName);

    }

    private static void testParameterizedType(String map) throws NoSuchFieldException {
        Field field1 = ParameterizedTypeTest.class.getDeclaredField(map);
        Type genericType1 = field1.getGenericType();
        String name1 = genericType1.getClass().getName();
        System.out.println("Class Name: "+name1);
        ParameterizedType parameterizedType = (ParameterizedType) genericType1;
        // 1.getActualTypeArguments
        // 获取泛型中的实际类型
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        System.out.println("Type Name start...");
        for (Type actualTypeArgument : actualTypeArguments) {
            System.out.println(actualTypeArgument);
        }
        System.out.println("Type Name end...");
        // 2. getOwnerType
        // 获取泛型的拥有者 拥有者表示的含义--内部类的父类
        Type ownerType = parameterizedType.getOwnerType();
        System.out.println("OwnerType: " + ownerType);
        // 3. getRawType
        // 获取声明泛型的类/接口
        Type rawType = parameterizedType.getRawType();
        System.out.println("RawType: " + rawType);
    }
}
